package com.agmte.api.common.crud.utils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 命名格式转换工具类：
 * - 驼峰转下划线（camelCase → snake_case）
 * - 下划线转驼峰（snake_case → camelCase）
 */
public final class NamingCaseUtils {

    private static final Pattern CAMEL_CASE_PATTERN = Pattern.compile("([A-Z])");
    private static final Pattern SNAKE_CASE_PATTERN = Pattern.compile("_([a-z])");

    /**
     * 驼峰命名 → 下划线命名（如：userName → user_name）
     */
    public static String camelToSnake(String camelCaseStr) {
        if (camelCaseStr == null || camelCaseStr.isEmpty()) {
            return camelCaseStr;
        }

        Matcher matcher = CAMEL_CASE_PATTERN.matcher(camelCaseStr);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(1).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 下划线命名 → 驼峰命名（如：user_name → userName）
     *
     * @param snakeCaseStr     下划线命名字符串
     * @param firstLetterLower 首字母是否小写（true: userName, false: UserName）
     */
    public static String snakeToCamel(String snakeCaseStr, boolean firstLetterLower) {
        if (snakeCaseStr == null || snakeCaseStr.isEmpty()) {
            return snakeCaseStr;
        }

        Matcher matcher = SNAKE_CASE_PATTERN.matcher(snakeCaseStr);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);

        // 处理首字母大小写
        if (sb.length() > 0) {
            char firstChar = sb.charAt(0);
            if (firstLetterLower) {
                sb.setCharAt(0, Character.toLowerCase(firstChar));
            } else {
                sb.setCharAt(0, Character.toUpperCase(firstChar));
            }
        }

        return sb.toString();
    }

    // 默认首字母小写（如：user_name → userName）
    public static String snakeToCamel(String snakeCaseStr) {
        return snakeToCamel(snakeCaseStr, true);
    }
}
